import 'dart:convert';
import 'dart:core';
import 'dart:io';

import 'package:hive/hive.dart';
import 'package:mysql1/mysql1.dart';

import '../models/dsItem.dart';
import 'screw.dart';

class DataSource {
  bool _isConnect = false;
  var _dirPath = '';
  DSItem _item;
  MySqlConnection _connection;

  bool get isConnect => _isConnect;

  Future<bool> connectFromHive(String entry) async {
    if (_dirPath.isEmpty) _dirPath = await Screw.getUserFilePath('flutter');
    if (!Hive.isAdapterRegistered(11)) Hive.registerAdapter(DSItemAdapter());
    var box = await Hive.openBox('dataSource', path: _dirPath);
    DSItem item = box.get(entry);
    if (item == null) return false;
    var setting = ConnectionSettings(
      timeout: Duration(seconds: 10),
      host: item.host,
      port: item.port,
      user: item.user,
      password: item.pwd,
      db: item.db,
    );
    await box.close();
    _connection = await MySqlConnection.connect(setting);
    _isConnect = _connection == null ? false : true;
    return _isConnect;
  }

  Future<DSItem> getDSItem(String entry) async {
    if (_dirPath.isEmpty) _dirPath = await Screw.getUserFilePath('flutter');
    if (!Hive.isAdapterRegistered(11)) Hive.registerAdapter(DSItemAdapter());
    var box = await Hive.openBox('dataSource', path: _dirPath);
    var items = box.get(entry);
    await box.close();
    return items;
  }

  Future<bool> _loadConfig(String fileName) async {
    if (_dirPath.isEmpty) _dirPath = await Screw.getUserFilePath('flutter');
    var filePath = Screw.joinPath(_dirPath, fileName);
    var file = File(filePath);
    if (!file.existsSync())
      return false;
    else {
      var content = file.readAsStringSync();
      _item = DSItem.fromMap(json.decode(content));
      return !(_item == null);
    }
  }

  Future<void> saveConfig(String fileName, DSItem item) async {
    if (_dirPath.isEmpty) _dirPath = await Screw.getUserFilePath('flutter');
    var filePath = Screw.joinPath(_dirPath, fileName);
    var file = File(filePath);
    if (!file.existsSync()) file.createSync();

    var content = json.encode(item.toMap());
    await file.writeAsString(content);
  }

  Future<bool> connectDB(String fileName) async {
    bool result = await _loadConfig(fileName);
    if (!result)
      return false;
    else {
      var setting = ConnectionSettings(
          timeout: Duration(seconds: 10),
          host: _item.host,
          port: _item.port,
          user: _item.user,
          password: _item.pwd,
          db: _item.db);
      _connection = await MySqlConnection.connect(setting);
      _isConnect = _connection == null ? false : true;
      return _isConnect;
    }
  }

  Future<void> close() async {
    if (_isConnect) {
      _connection.close();
      _connection = null;
    }
  }

  Future<Results> query(String sql, [List<Object> values]) async {
    return await _connection.query(sql, values);
  }
}
